예측 모형의 최종 성능을 객관적으로 측정하려면 모수 추정(parameter fitting) 즉 트레이닝(training)에 사용되지 않은 새로운 데이터, 즉 테스트 데이터를 사용해야 한다. 모형의 모수 갯수를 증가시킨다든가 커널 모형, 신경망 모형과 같은 비선형 모형을 사용하게 되면 트레이닝 데이터에 대한 예측 성능을 얼마든지 높일 수 있기 때문이다. 이러한 방법에 의해 과최적화(overfitting)가 일어나면 트레이닝 데이터에 대해서는 예측이 잘되지만 테스트 데이터에 대해서는 예측 성능이 급격히 떨어지는 현상이 발생한다.
위에서 지적한 바와 같이 모형 성능을 정상적으로 검사하려면 테스트 데이터가 별도로 있어야 하기 때문에 현실에서는 확보한 데이터 중 일부를 떼어내어 테스트 데이터로 사용한다. 그런데 테스트 데이터를 어떻게 골라내느냐에 따라 모형의 성능이 달라지므로 한 개의 테스트 데이터만 사용하는 것이 아니라 각기 다른 방법으로 서로 다른 테스트 데이터를 여러번 골라내서 복수의 테스트를 실시하는 것이 일반적이다.
이러한 테스트 방법을 교차 검증(cross validation)이라고 한다. 교차 검증을 통한 모형 성능은 보통 다음과 같은 두 가지 값으로 나타난다.
이 중에서 오차 분산을 계산하려면 테스트 데이터 셋이 최소한 세 개 세트가 있어야 한다.
Scikit-Learn에서는 교차 검증을 위해 전체 데이터 셋에서 트레이닝용 데이터나 테스트용 데이터를 분리해 내는 여러가지 방법을 제공한다.
train_test_split()
명령KFold
StratifiedKFold
LabelKFold
LeaveOneOut
LeavePOut
LeaveOneLabelOut
LeavePLabelOut
ShuffleSplit
LabelShuffleSplit
cross_val_score()
train_test_split()
명령은 데이터를 단순히 트레이닝 데이터와 테스트 데이터로 분리한다.
인수
반환값
In [1]:
X = np.arange(10).reshape((5, 2))
X
Out[1]:
In [2]:
y = np.arange(5)
y
Out[2]:
In [3]:
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
In [4]:
X_train
Out[4]:
In [5]:
y_train
Out[5]:
In [6]:
X_test
Out[6]:
In [7]:
y_test
Out[7]:
K-fold CV(cross-validation) 방법은 데이터 셋을 K개의 sub-set로 분리하는 방법이다. 분리된 K개의 sub-set 중 하나만 제외한 K-1개의 sub-sets를 training set으로 이용하여 K개의 모형 추정한다.
Scikit-Learn 의 cross_validation 서브 패키지는 K-Fold를 위한 KFold
클래스를 제공한다.
In [8]:
N = 5
X = np.arange(8 * N).reshape(-1, 2) * 10
y = np.hstack([np.ones(N), np.ones(N) * 2, np.ones(N) * 3, np.ones(N) * 4])
print("X:\n", X, sep="")
print("y:\n", y, sep="")
In [9]:
from sklearn.cross_validation import KFold
cv = KFold(len(X), n_folds=3, random_state=0)
for train_index, test_index in cv:
print("test y:", y[test_index])
print("." * 80 )
print("train y:", y[train_index])
print("=" * 80 )
In [11]:
from sklearn.cross_validation import StratifiedKFold
cv = StratifiedKFold(y, n_folds=3, random_state=0)
for train_index, test_index in cv:
print("test X:\n", X[test_index])
print("." * 80 )
print("test y:", y[test_index])
print("=" * 80 )
In [10]:
from sklearn.cross_validation import LeaveOneOut
cv = LeaveOneOut(5)
for train_index, test_index in cv:
print("test X:", X[test_index])
print("." * 80 )
print("test y:", y[test_index])
print("=" * 80 )
In [12]:
from sklearn.cross_validation import LabelKFold
cv = LabelKFold(y, n_folds=3)
for train_index, test_index in cv:
print("test y:", y[test_index])
print("." * 80 )
print("train y:", y[train_index])
print("=" * 80 )
In [13]:
from sklearn.cross_validation import ShuffleSplit
cv = ShuffleSplit(5)
for train_index, test_index in cv:
print("test X:", X[test_index])
print("=" * 20 )
CV는 단순히 데이터 셋을 나누는 역할을 수행할 뿐이다. 실제로 모형의 성능(편향 오차 및 분산)을 구하려면 이렇게 나누어진 데이터셋을 사용하여 평가를 반복하여야 한다. 이 과정을 자동화하는 명령이 cross_val_score()
이다.
cross_val_score(estimator, X, y=None, scoring=None, cv=None)
cv
를 이용하여 X
, y
data 를 분할하고 estimator
에 넣어서 scoring
metric을 구하는 과정을 반복인수
반환값
In [14]:
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
X, y, coef = make_regression(n_samples=1000, n_features=1, noise=20, coef=True, random_state=0)
model = LinearRegression()
cv = KFold(1000, 10)
scores = np.zeros(10)
for i, (train_index, test_index) in enumerate(cv):
X_train = X[train_index]
y_train = y[train_index]
X_test = X[test_index]
y_test = y[test_index]
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
scores[i] = mean_squared_error(y_test, y_pred)
scores
Out[14]:
In [15]:
from sklearn.cross_validation import cross_val_score
cross_val_score(model, X, y, "mean_squared_error", cv)
Out[15]:
r2_score(y_true, y_pred[, ...])
: R^2 (coefficient of determination) regression score function.explained_variance_score(y_true, y_pred)
: Explained variance regression score functionmean_squared_error(y_true, y_pred[, ...])
: Mean squared error regression lossmean_absolute_error(y_true, y_pred)
: Mean absolute error regression lossmedian_absolute_error(y_true, y_pred)
: Median absolute error regression loss